package com.stm.bi.report;

import com.stm.bi.core.util.DateUtils;
import com.stm.bi.model.Chart;
import com.stm.framework.core.util.FileResourceLoader;
import com.stm.framework.core.util.StringUtil;
import com.stm.framework.dbcp.JdbcService;
import com.stm.bi.constant.PaisiConstants;
import com.stm.bi.dto.query.PolicyEvolveTotalChartQuery;
import com.stm.bi.enums.PolicyEvolveType;
import com.stm.ucenter.dto.vo.TreeVO;
import jakarta.annotation.Resource;
import org.springframework.stereotype.Component;

import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.*;
import java.util.stream.Collectors;


/**
 * @author liuyx
 * @date 2025/2/14 9:09
 */
@Component
public class PolicyEvolveTotalChartQueryExe extends AbsChartQueryExe<PolicyEvolveTotalChartQuery, Chart<List<List<Object>>>> {
    @Resource
    private JdbcService jdbcService;

    @Resource
    private PolicyEvolveDatatableQueryExe policyEvolveDatatableQueryExe;


    @Override
    public Chart query(Long orgId, String orgNo, PolicyEvolveTotalChartQuery query) {

        List<String> dates = DateUtils.getReportDateList(query.getStartDate(), query.getEndDate(), query.getDateType().getValue());

        Chart<List<List<Object>>> chart = getChart();

        // 获取左侧栏项目
        List<TreeVO> treeList = policyEvolveDatatableQueryExe.getRowInfoTrees(query.getPolicyId(), query.getType(), Boolean.FALSE);
        if (StringUtil.isEmpty(treeList)) {
            return chart;
        }

        // 定制化新老商品
        if (query.getType().equals(PolicyEvolveType.PRODUCT_FEATURE.getValue())) {
            // 过滤复制
            treeList = treeList.stream().filter(item -> Boolean.TRUE.equals(item.getSelectable())).toList();
            chart = getChart(treeList);
        }

        // id列表
        List<Long> idList = treeList.stream().map(TreeVO::getId).toList();
        List<Map> maps;
        if (StringUtil.isEmpty(idList)) {
            maps = new ArrayList<>();
        } else {
            maps = getOriginalData(orgNo, query.getType(), query.getDateType().getValue(), dates, idList);
        }

        setChartData(maps, chart, query, treeList, dates);

        return chart;
    }

    public List<Map> getOriginalData(String orgNo, String type, String dateType, List<String> dates, List<Long> idList) {

        String selectSql;
        switch (type) {
            case PaisiConstants.CORE_MARKET_POLICY:
                // 部门bu
                selectSql = FileResourceLoader.getResourceAsString("/sql/policyEvolve/adsResDeptSalesByIds.sql");
                break;
            case PaisiConstants.INDUSTRY_RESOURCES_POLICY:
            case PaisiConstants.CUSTOMER_LEVEL_POLICY:
            case PaisiConstants.CUSTOMER_FEATURES_POLICY:
                // 顾客
                selectSql = FileResourceLoader.getResourceAsString("/sql/policyEvolve/adsResPolicyCustomerSalesByIds.sql");
                break;
            case PaisiConstants.PRODUCT_CATEGORY_POLICY:
            case PaisiConstants.PRODUCT_FEATURE_POLICY:
                // 商品
                selectSql = FileResourceLoader.getResourceAsString("/sql/policyEvolve/adsResPolicyProductSalesByIds.sql");
                break;
            default:
                selectSql = FileResourceLoader.getResourceAsString("/sql/policyEvolve/adsResPolicyProductSalesByIds.sql");
        }

        // 将idList转换为逗号分隔的字符串
        String idListStr = idList.stream().map(String::valueOf).collect(Collectors.joining(","));
        // 替换SQL中的占位符
        selectSql = selectSql.replace("{policyIds}", idListStr);

        List<Map> maps = jdbcService.selectList(selectSql, new Object[]{
                orgNo,
                dateType,
                type,
                dates.getFirst(),
                dates.getLast()}
        );
        return maps;
    }

    /**
     * 建立图表栏
     *
     * @return
     */
    private Chart<List<List<Object>>> getChart() {
        Chart<List<List<Object>>> chart = new Chart<>();
        List<String> items = chart.getItems();
        items.add(PaisiConstants.SALES_NAME);
        items.add(PaisiConstants.CUSTOMER_NUM_NAME);
        chart.setItems(items);
        return chart;
    }

    private Chart<List<List<Object>>> getChart(List<TreeVO> treeList) {
        Chart<List<List<Object>>> chart = new Chart<>();
        List<String> items = chart.getItems();
        for (TreeVO treeVO : treeList) {
            items.add(treeVO.getLabel() + PaisiConstants.SALES_NAME);
        }
        for (TreeVO treeVO : treeList) {
            items.add(treeVO.getLabel() + PaisiConstants.CUSTOMER_NUM_NAME);
        }

        chart.setItems(items);

        return chart;
    }

    /**
     * 构建图表数据
     * @param maps
     * @param chart
     * @param query
     * @param treeList
     * @param dates
     */
    public void setChartData(List<Map> maps, Chart<List<List<Object>>> chart, PolicyEvolveTotalChartQuery query, List<TreeVO> treeList, List<String> dates) {

        List<String> valueColumns = new ArrayList<>();
        Map<Long, String> idCodeMap = new HashMap<>();

        valueColumns.add(PaisiConstants.SALES_COLUMN);
        valueColumns.add(PaisiConstants.CUSTOMER_NUM_COLUMN);

        List<String> codeList = new ArrayList<>();


        if (PaisiConstants.PRODUCT_FEATURE_POLICY.equals(query.getType())) {
            for (TreeVO treeVO : treeList) {
                idCodeMap.put(treeVO.getId(), treeVO.getCode());
                codeList.add(treeVO.getCode() + "-" + PaisiConstants.SALES_COLUMN);
            }
            for (TreeVO treeVO : treeList) {
                codeList.add(treeVO.getCode() + "-" + PaisiConstants.CUSTOMER_NUM_COLUMN);
            }
        } else {
            codeList.add(PaisiConstants.SALES_COLUMN);
            codeList.add(PaisiConstants.CUSTOMER_NUM_COLUMN);
        }


        // 日期，列表，数据
        Map<String, Map<String, BigDecimal>> totalMap = new LinkedHashMap<>();

        // 计算合计
        for (Map obj : maps) {
            String date = obj.get(PaisiConstants.DATE_COLUMN).toString();
            Long id = (Long) obj.get("policy_id");

            if (!totalMap.containsKey(date)) {
                totalMap.put(date, new LinkedHashMap<>());
            }
            Map<String, BigDecimal> dateTotalMap = totalMap.get(date);
            for (String valueColumn : valueColumns) {
                BigDecimal value = new BigDecimal(obj.get(valueColumn).toString());
                if (idCodeMap.containsKey(id)) {
                    String key = idCodeMap.get(id) + "-" + valueColumn;
                    dateTotalMap.put(key, dateTotalMap.getOrDefault(key, BigDecimal.ZERO).add(value));
                } else {
                    dateTotalMap.put(valueColumn, dateTotalMap.getOrDefault(valueColumn, BigDecimal.ZERO).add(value));
                }
            }
        }
        // 拼接
        List<List<Object>> data = new ArrayList<>();

//        String lastDate = totalMap.keySet().stream()
//                .max(String::compareTo)
//                .orElse(null);
        String lastDate = DateUtils.getCurrentDate().substring(0,7);

        for (String date : dates) {
            List<Object> row = new ArrayList<>();
            row.add(DateUtils.getReportDateName(date, query.getDateType().getValue()));

            Map<String, BigDecimal> dateMap = totalMap.get(date);
            if (dateMap != null) {
                for (String code : codeList) {
                    // 转万元
                    if (code.contains(PaisiConstants.SALES_COLUMN)) {
                        row.add(dateMap.getOrDefault(code, BigDecimal.ZERO).divide(new BigDecimal(10000), 2, RoundingMode.HALF_UP));
                    } else {
                        row.add(dateMap.getOrDefault(code, BigDecimal.ZERO).setScale(0, RoundingMode.HALF_UP));
                    }
                }
                // 最后月份前空值补零
            } else if (lastDate!= null && date.compareTo(lastDate) <= 0) {
                codeList.forEach(code -> row.add(BigDecimal.ZERO));
            }
            data.add(row);
        }
        chart.setDatas(data);

        List<List<Object>> extend = getExtendData(codeList, totalMap, treeList);
        chart.setExtend(extend);
    }


    private List<List<Object>> getExtendData(List<String> codeList, Map<String, Map<String, BigDecimal>> totalMap, List<TreeVO> treeList) {

        List<List<Object>> extend = new ArrayList<>();
        Map<String, BigDecimal> valueTotalMap = new LinkedHashMap<>();
        totalMap.forEach((date, dateMap) -> {
            for (String code : codeList) {
                valueTotalMap.put(code, valueTotalMap.getOrDefault(code, BigDecimal.ZERO).add(dateMap.getOrDefault(code, BigDecimal.ZERO)));
            }
        });

        valueTotalMap.forEach((code, value) -> {
            String prefixName;
            if (code.contains("new")) {
                prefixName = "新商品";
            } else if (code.contains("old")) {
                prefixName = "老商品";
            } else {
                prefixName = "";
            }

            List<Object> row = new ArrayList<>();

            // 销售额
            if (code.contains(PaisiConstants.SALES_COLUMN)) {
                row.add(prefixName + PaisiConstants.SALES_NAME + "(万)");
                row.add(value.divide(new BigDecimal(10000), 2, RoundingMode.HALF_UP));
            } else {
                row.add(prefixName + PaisiConstants.CUSTOMER_NUM_NAME + "(位)");
                row.add(value.setScale(0, RoundingMode.HALF_UP));
            }
            row.add(null);
            row.add(0);
            extend.add(row);
        });

        return extend;
    }

    @Override
    public String getReportName() {
        return "方针占比推移合计表";
    }


}
